package cn.com.dingtek.genius.manager.server.service;

import cn.com.dingtek.genius.manager.server.repository.db.entity.AuthGroup;
import cn.com.dingtek.genius.manager.server.repository.db.entity.CompanyBase;
import cn.com.dingtek.genius.manager.server.repository.db.entity.UserBase;
import cn.com.dingtek.genius.manager.server.repository.db.manager.AuthGroupManager;
import cn.com.dingtek.genius.manager.server.repository.db.manager.CompanyBaseManager;
import cn.com.dingtek.genius.manager.server.repository.db.manager.UserBaseManager;
import cn.com.dingtek.genius.manager.server.utils.MybatisPlusUtil;
import cn.com.dingtek.genius.manager.server.utils.Verify;
import cn.com.dingtek.genius.manager.server.utils.VerifyException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserService {
    @Autowired
    private UserBaseManager userBaseManager;
    @Autowired
    private CompanyBaseManager companyBaseManager;
    @Autowired
    private AuthGroupManager authGroupManager;

    public JSONObject list(UserBase param, int currentPage, int pageSize) {
        QueryWrapper<UserBase> query = Wrappers.emptyWrapper();
        if (param != null) {
            query = MybatisPlusUtil.customEqQuery(null, "company_id", param.getCompanyId());
            query = MybatisPlusUtil.customEqQuery(query, "account_name", param.getAccountName());
            query = MybatisPlusUtil.customEqQuery(query, "mobile", param.getMobile());
            query = MybatisPlusUtil.customEqQuery(query, "email", param.getEmail());
        }

        IPage<UserBase> userBasePage = userBaseManager.page(new Page<UserBase>(currentPage, pageSize).setDesc("id"), query);

        List<JSONObject> records = userBasePage.getRecords().stream()
                .map(item -> {
                    JSONObject jsonObject = (JSONObject) JSON.toJSON(item);

                    AuthGroup authGroup = authGroupManager.getById(item.getAuthGroupId());
                    String authGroupName = "--";
                    if (authGroup != null) {
                        authGroupName = authGroup.getGroupName();
                    }

                    CompanyBase companyBase = companyBaseManager.getById(item.getCompanyId());
                    String companyName = "--";
                    if (companyBase != null) {
                        companyName = companyBase.getCompanyName();
                    }
                    return jsonObject.fluentPut("authGroupName", authGroupName).fluentPut("companyName", companyName);
                })
                .collect(Collectors.toList());
        return new JSONObject().fluentPut("total", userBasePage.getTotal())
                .fluentPut("records", records);
    }


    public void add(UserBase param, Date now) {
        String passwdHash = DigestUtils.md5DigestAsHex(param.getPasswd().getBytes(StandardCharsets.UTF_8));
        try {
            Verify.isTrue(userBaseManager.save(UserBase.builder()
                    .accountName(param.getAccountName())
                    .passwd(passwdHash)
                    .authGroupId(param.getAuthGroupId())
                    .companyId(param.getCompanyId())
                    .mobile(param.getMobile())
                    .email(param.getEmail())
                    .address(param.getAddress())
                    .remark(param.getRemark())
                    .ctime(now)
                    .utime(now)
                    .version(0).build()), "新增用户失败.");
        } catch (DuplicateKeyException e) {
            throw new VerifyException("该账号已存在");
        }
    }

    public UserBase info(Long id) {
        Verify.isTrue(id != null && id > 0, "用户不存在");
        return userBaseManager.getById(id);
    }

    public void update(UserBase param, Date now) {
        Verify.isTrue(param.getId() != null && param.getId() > 0, "用户不存在");

        UserBase userBase = userBaseManager.getById(param.getId());
        Verify.notNull(userBase, "用户不存在");

        UserBase toUpdate = UserBase.builder().id(userBase.getId())
                .companyId(param.getCompanyId())
                .authGroupId(param.getAuthGroupId())
                .mobile(param.getMobile())
                .email(param.getEmail())
                .address(param.getAddress())
                .remark(param.getRemark())
                .utime(now)
                .version(userBase.getVersion()).build();

        Verify.isTrue(userBaseManager.updateById(toUpdate), "更新用户失败");
    }

    public void remove(Long id) {
        if (id != null && id > 0) {
            userBaseManager.removeById(id);
        }
    }

    public void repasswd(Long id, String newPasswd, Date now) {
        Verify.isTrue(id != null && id > 0, "用户不存在");

        UserBase userBase = userBaseManager.getById(id);
        Verify.notNull(userBase, "用户不存在");

        String passwdHash = DigestUtils.md5DigestAsHex(newPasswd.getBytes(StandardCharsets.UTF_8));
        UserBase toUpdate = UserBase.builder().id(id).passwd(passwdHash).utime(now).version(userBase.getVersion()).build();

        Verify.isTrue(userBaseManager.updateById(toUpdate), "更新密码失败");
    }

    public void grant(Long userId, Long authGroupId, Date now) {
        Verify.isTrue(userId != null && userId > 0, "用户不存在");
        Verify.isTrue(authGroupId != null && authGroupId > 0, "角色不存在");

        UserBase userBase = userBaseManager.getById(userId);
        Verify.notNull(userBase, "用户不存在");

        AuthGroup userAuthGroup = authGroupManager.getById(authGroupId);
        Verify.notNull(userAuthGroup, "角色不存在");

        UserBase toUpdate = UserBase.builder().id(userId).authGroupId(userAuthGroup.getId()).utime(now).version(userBase.getVersion()).build();
        Verify.isTrue(userBaseManager.updateById(toUpdate), "授权失败");
    }
}
